package com.heima.notice.configuration;


import com.alibaba.fastjson.JSON;
import com.heima.modules.po.NoticePO;
import com.heima.notice.service.NoticeService;
import com.heima.notice.socket.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.Session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务 推送暂存消息
 */
@Component
public class ScheduledTask {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledTask.class);

    @Autowired
    private NoticeService noticeService;

    private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);

    @PostConstruct
    public void init() {
        //TODO:任务5.2-推送未读消息
        //定时调度，获取mongodb里的未读消息，推送给对应用户
        executorService.scheduleAtFixedRate(() -> {

            //获取所有在线的用户accountId，提示：WebSocketServer里有用户链接的池子
            List<String> accountIdList = new ArrayList<>();
            WebSocketServer.sessionPools.forEach((accountId,session)->{
                accountIdList.add(accountId);
            });
            logger.debug("获取所有在线的用户accountId线程工作中,数据条数:{}",accountIdList.size());

            //在MongoDB中获取需要推送的消息，noticeService里的方法研究一下，可以帮到你
            List<NoticePO> noticePOList=noticeService.getNoticeByAccountIds(accountIdList);

            if (null!=noticePOList&&!noticePOList.isEmpty()) {
                logger.debug("推送消息线程工作中,推送数据条数:{}", noticePOList.size());

                for (NoticePO noticePO : noticePOList) {
                    String receiverId = noticePO.getReceiverId();
                    String message = noticePO.getMessage();

                    if (receiverId != null && message != null) {
                        Session session = WebSocketServer.sessionPools.get(receiverId);
                        if (session != null) {
                            try {
                                session.getAsyncRemote().sendText(message);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }
                ;
            }
            //遍历所有消息，逐个发送消息到浏览器
            //方法：session.getBasicRemote().sendText(json);

        }, 0,1 , TimeUnit.SECONDS);
    }

}
/*
  //TODO:任务5.2-推送未读消息
        //定时调度，获取mongodb里的未读消息，推送给对应用户
        executorService.scheduleAtFixedRate(() -> {
//           //获取最新需要推送的消息

//这行代码的作用是获取 WebSocketServer.sessionPools 中所有键（String 类型）的集合，并将其存储在 accountKeys 变量中
//keySet() 方法 作用：keySet() 是 Map 接口中的一个方法，用于返回一个包含 Map 中所有键的集合。
//返回值：Set<String> 类型，包含 sessionPools 中所有的键
// 关键点
//动态视图：keySet() 返回的集合是 Map 的动态视图。如果 Map 的内容发生变化（如添加或删除条目），keySet() 返回的集合也会相应地更新。
//不可修改：keySet() 返回的集合是只读的，不能直接添加或删除元素。如果需要修改 Map 的内容，必须通过 Map 本身的方法（如 put、remove）进行操作。

            Set<String> accountKeys = WebSocketServer.sessionPools.keySet();

            // logger.info("msg task working,inline accounts:{}",accountIds);
            if (accountKeys == null || accountKeys.isEmpty()){
                return;
            }
            //在MongoDB中获取当前在线用户的暂存消息
            List<String> accountIds = new ArrayList<>(accountKeys.size());
            accountIds.addAll(accountKeys);
            List<NoticePO> pushMessagesList = noticeService.getNoticeByAccountIds(accountIds);

            //校验消息
            if (null != pushMessagesList && !pushMessagesList.isEmpty()) {

                logger.debug("推送消息线程工作中,推送数据条数:{}", pushMessagesList.size());
                //推送消息
                for (NoticePO noticePO : pushMessagesList) {
                    //获取当前会话
                    Session session = WebSocketServer.sessionPools.get(noticePO.getReceiverId());
                    if (null != session && null != noticePO) {
                        //获取消息体
                        try {
                            session.getBasicRemote().sendText(JSON.toJSONString(noticePO));
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }
            logger.debug("推送消息线程工作中,推送数据条数:{}", 0);
        }, 0,1 , TimeUnit.SECONDS);
    }
    */